package com.mdlaser.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import com.mdlaser.api.ResponseResult;
import com.mdlaser.enums.DeviceType;
import com.mdlaser.sys.entity.User;
import com.mdlaser.sys.service.IUserService;
import com.mdlaser.util.JsonUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Map;


@RestController
@AllArgsConstructor
@Tag(name = "微信公众号")
@RequestMapping("/wxcommon")
@Slf4j
public class WxPortalController {


    private final WxMpService wxService;

    @Autowired
    IUserService userService;

    @GetMapping(value = "/", produces = "text/plain;charset=utf-8")
    @Operation(summary = "微信鉴权", description = "微信鉴权")
    @SaIgnore
    public String authGet(@RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr) {

        log.info("\n接收到来自微信服务器的认证消息：[{}, {}, {}, {}]", signature,
                timestamp, nonce, echostr);
        if (StringUtils.isAnyBlank(signature, timestamp, nonce)) {
            throw new IllegalArgumentException("请求参数非法，请核实!");
        }


        if (wxService.checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }

        return "非法请求";
    }

    @SaIgnore
    @GetMapping(value = "/login")
    @Operation(summary = "微信登录", description = "微信登录")
    public ResponseResult<Object> login(
            @RequestParam(name = "appid", required = true) String appid,
            @RequestParam(name = "secret", required = true) String secret,
            @RequestParam(name = "code", required = true) String code) {
        RestTemplate restTemplate = new RestTemplate();
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid
                + "&secret=" + secret
                + "&code=" + code
                + "&grant_type=authorization_code";
        String resText = restTemplate.getForObject(url, String.class);
        Map<String, String> resMap = JsonUtil.deserializeObject(resText, Map.class);
        if (resMap != null) {
            String token = resMap.get("access_token");
            String openid = resMap.get("openid");
            if (token != null) {
                User user = userService.getUserById(openid);
                if (user == null) {
                    user = new User();
                    user.setNickName(openid);
                    user.setUserName(openid);
                    user.setId(openid);
                    user.setAvatar(openid);
                    user.setPassWord("weixin@123456");
                    userService.addUser(user);
                }

                //刷新用户信息
                try {
                    String authInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + openid + "&lang=zh_CN";
                    String authInfoText = restTemplate.getForObject(authInfoUrl, String.class);
                    Map<String, String> authInfoMap = JsonUtil.deserializeObject(authInfoText, Map.class);
                    String nickname = authInfoMap.get("nickname");
                    nickname = new String(nickname.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
                    String avatar = authInfoMap.get("headimgurl");
                    user.setNickName(nickname);
                    user.setAvatar(avatar);
                    userService.getBaseMapper().updateById(user);
                } catch (RestClientException e) {
                    throw new RuntimeException("获取用户信息失败，原因" + e.getMessage());
                }

                StpUtil.login(openid, new SaLoginModel()
                        .setDevice(DeviceType.MOBILE)                // 此次登录的客户端设备类型, 用于[同端互斥登录]时指定此次登录的设备类型
                        .setIsLastingCookie(true)        // 是否为持久Cookie（临时Cookie在浏览器关闭时会自动删除，持久Cookie在重新打开后依然存在）
                        .setTimeout(60 * 60 * 24 * 7)    // 指定此次登录token的有效期, 单位:秒 （如未指定，自动取全局配置的 timeout 值）
                        .setIsWriteHeader(true)
                        .setToken(token)       // 是否在登录后将 Token 写入到响应头
                );
                return ResponseResult.success("登陆成功", token);
            }
        }

        throw new RuntimeException("登陆失败，错误信息" + JsonUtil.serialObject(resMap));


    }


}
